﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace BTSZap
{
    internal static class Log
    {

        private static int _indent;
        private static int _indentBy = 2;



        private static string FormatException(int indent,Exception ex)
        {
            StringBuilder bld = new StringBuilder();
            int originalIdent = indent;
            bld.AppendFormat("{0}Exception raised\n", String.Empty.PadLeft(indent));
            bld.AppendFormat("{0}----------------\n", String.Empty.PadLeft(indent));
            bld.AppendFormat("{0}{1}:{2}\n", String.Empty.PadLeft(indent), ex.GetType().Name, ex.Message);
            bld.AppendFormat("{0} Call stack\n", String.Empty.PadLeft(indent));
            
            StackTrace stk = new StackTrace(ex);
            foreach (StackFrame frame in stk.GetFrames())
            {
                indent++;                
                bld.AppendFormat("{0}{1} line:{2}\n", String.Empty.PadLeft(indent), frame.GetMethod().Name,frame.GetFileLineNumber());
            }
            bld.AppendFormat("{0}----------------\n", String.Empty.PadLeft(originalIdent));
            return bld.ToString();
        }

        public static int IdentBy { get { return _indentBy; } set { _indentBy = value; } }
        public static void Indent()
        {
            _indent+=IdentBy;
        }
        public static void UnIndent()
        {
            _indent-=IdentBy;
            if (_indent < 0) _indent = 0;
        }
        public static void ResetIdent()
        {
            _indent = 0;
        }

        public static void WriteWarning(string format, params object[] args)
        {
            if (Arguments.Current.InfoLevel >= 2)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine(String.Empty.PadLeft(_indent) + String.Format(format, args));
                Console.ResetColor();
            }
        }

        public static void WriteEndWarning(string format, params object[] args)
        {
            WriteWarning(format, args);
            UnIndent();
        }
        public static void WriteError(string format, params object[] args)
        {
            if (Arguments.Current.InfoLevel >= 1)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(String.Empty.PadLeft(_indent) + String.Format(format,args));
                Console.ResetColor();
            }
        }
        public static void WriteException(Exception ex)
        {
            if (Arguments.Current.InfoLevel >= 3)
            {
                Indent();
                Console.WriteLine(FormatException(_indent,ex));
                UnIndent();
            }
        }
        public static void WriteInformation(string format, params object[] args)
        {
            if (Arguments.Current.InfoLevel >= 2)
            {
                Console.WriteLine(String.Empty.PadLeft(_indent) + String.Format(format, args));
            }
        }
        public static void WriteSucess(string format, params object[] args)
        {
            if (Arguments.Current.InfoLevel >= 2)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(String.Empty.PadLeft(_indent) + String.Format(format, args));
                Console.ResetColor();
            }
        }
        public static void WriteStartInformation(string format, params object[] args)
        {
            Indent();
            WriteInformation(format, args);
        }
        public static void WriteEndInformation(string format, params object[] args)
        {            
            WriteInformation(format, args);
            UnIndent();
        }

        public static void WriteEndSucess(string format, params object[] args)
        {            
            WriteSucess(format, args);
            UnIndent();
        }
        public static void WriteEndError(string format, params object[] args)
        {            
            WriteError(format, args);
            UnIndent();
        }

        private static System.Threading.Timer tim;
        private static void Tick(object state)
        {
            Console.Write('.');
        }
        public static void StartWait()
        {
            tim = new System.Threading.Timer(new System.Threading.TimerCallback(Tick),null,new TimeSpan(0,0,1),new TimeSpan(0,0,1));            
        }
        public static void StopWait()
        {
            tim.Dispose();
            tim = null;
            Console.WriteLine();
        }
    }
}
